home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / gen / bstone / borlandc / bstone_y.y < prev    next >
Encoding:
Lex Description  |  1994-03-21  |  24.5 KB  |  894 lines

  1. %{
  2. #define YYDEBUG 0
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <math.h>
  6. #include <alloc.h>
  7. #include <string.h>
  8. #include "t_cio.h"
  9. #include "vector.h"
  10. #include "t_lex.h"
  11. #include "bstone_m.h"
  12. LEX *lex;
  13. FILE *errlogz=stderr;
  14. FILE *pvp=stdout;
  15. int ybdebug=0;
  16. int load_flag=0;
  17. int fkt_id;
  18. POV_OBJ **obj_all;
  19. static int i,id1,id2,k;
  20. static DIM_H dm;
  21. static long n;
  22. static T_NODE *tn;
  23. static FT_LOOP *ft;
  24. static double dd;
  25. static double *dp;
  26. static POV_OBJ pv_obj;
  27. static char pv_line[LSIZE];
  28. static int n_obj;
  29. static POV_OBJ *obj_lst[BSIZE];
  30. static POV_OBJ *pv;
  31. static VECTOR v;
  32. static char *ys;
  33.  
  34. %}
  35. %TOKEN Y_VAL Y_VEC Y_ABS Y_STR Y_END Y_REM Y_GOTO Y_TRACE
  36.        Y_LET Y_PRINT Y_LIST Y_OBJ Y_V0 Y_VX Y_VY Y_VZ
  37.        Y_LOAD Y_SAVE Y_IF Y_THEN Y_CONT Y_STOP Y_GOSUB Y_RETURN
  38.        Y_DELETE Y_NUM Y_DIM Y_FOR Y_TO Y_STEP Y_NEXT Y_NEW Y_RUN
  39.        Y_FKT Y_RND Y_FOPEN Y_FPRINT Y_PLANE Y_BIT Y_BOUND Y_TEX
  40.        Y_TRANSFORM
  41. %union { double s; double v[3]; T_NODE *t; POV_OBJ *p; }
  42. %type <s> i_expr
  43. %type <s> i_exprx
  44. %type <s> i_expry
  45. %type <s> i_exprz
  46. %type <s> i_term
  47. %type <s> i_faktor
  48. %type <s> f_step
  49. %type <v> v_expr
  50. %type <v> v_exprz
  51. %type <v> v_term
  52. %type <v> v_faktor
  53. %type <t> Y_VEC
  54. %type <t> y_vec
  55. %type <t> Y_VAL
  56. %type <t> y_val
  57. %type <t> Y_NUM
  58. %type <t> Y_STR
  59. %type <p> Y_OBJ
  60. %type <p> y_obj
  61. %%
  62. anw     : { if(ybdebug && !transl_flag)
  63.           {
  64.            if(program_ctr>=0)
  65.          fprintf(errlogz,"* %-6d ",program[program_ctr-1].n);
  66.            else fprintf(errlogz,"* C      ");
  67.            fprintf(errlogz,"%s\n",retransl_line(clines));
  68.           }
  69.       } anwg
  70.       { if(!transl_flag)
  71.           { if(ybdebug==1)
  72.           {
  73. #ifdef __TURBOC__
  74.             fprintf(stderr,"* %ld Bytes free\n",coreleft());
  75. #endif
  76.             putc('*',stderr);
  77.             gets(tmp_line);  /* TRAP */
  78.             if(tmp_line[0] && (tmp_line[0]!='y') && (tmp_line[0]!='Y'))
  79.               { if(program_ctr>=0) cont_line=program[program_ctr].n;
  80.             program_ctr=-1; }
  81.           }
  82.         /* perform DOS-action */
  83. #ifdef __MSDOS__
  84.         if(break_en)  { putchar('\r'); }
  85. #endif
  86.         if(break_req)
  87.           { break_req=0;
  88.             if(program_ctr>=0) cont_line=program[program_ctr].n;
  89.             if(program_ctr>=0)
  90.               printf(".. break at line %d\n",cont_line);
  91.             program_ctr=-1; }
  92.       }}
  93.  
  94. anwg    :
  95.  
  96.     | Y_END { if(!transl_flag) program_ctr=-1; }
  97.  
  98.     | Y_STOP { if(!transl_flag)
  99.              { if(program_ctr>=0) cont_line=program[program_ctr].n;
  100.                if(program_ctr>=0)
  101.              printf(".. stopped at line %d\n",cont_line);
  102.                program_ctr=-1; }}
  103.  
  104.     | Y_CONT { if(!transl_flag)
  105.              if(cont_line>=0) program_ctr=search_line(cont_line); }
  106.  
  107.     | Y_REM
  108.       { if(transl_flag)
  109.           { do
  110.           {
  111.            lex=t_lex(NULL,LEX_RCHAR);
  112.            cline[clinep++]=(char)(id1=lex->wert.n.i);
  113.           }
  114.         while((id1!='\n') && (lex->typ!=EOLX));
  115.         clinep-=1;
  116.         lex->typ=EOLN; t_lex(NULL,LEX_PUSH);
  117.           }
  118.         else for(;*(clines+clinep)!=(char)0;clinep++);
  119.      }
  120.  
  121.     | Y_IF i_expr Y_THEN
  122.       { if(!transl_flag && !($2))
  123.           for(;*(clines+clinep)!=(char)0;clinep++); }
  124.       anwg
  125.  
  126.     | Y_IF i_expr Y_GOTO Y_NUM
  127.       { if(!transl_flag && ($2))
  128.           program_ctr=search_line((int)(*(VEC)(($4)->p))); }
  129.  
  130.  
  131.     | Y_GOTO Y_NUM
  132.       { if(!transl_flag) program_ctr=search_line((int)(*(VEC)(($2)->p))); }
  133.  
  134.     | Y_RUN        { if(!transl_flag)
  135.                { gosub_ptr=0; program_ctr=0; }}
  136.     | Y_RUN i_expr { if(!transl_flag)
  137.                { gosub_ptr=0;
  138.                  program_ctr=search_line((int)($2)); }}
  139.  
  140.     | Y_GOSUB Y_NUM
  141.       { if(!transl_flag)
  142.           { if(gosub_ptr>=MAX_LINES/10)
  143.           t_error("Gosub stack overflow.",4);
  144.         if(program_ctr>=0)
  145.           gosub_stack[gosub_ptr++]=program[program_ctr].n;
  146.         else
  147.           gosub_stack[gosub_ptr++]=-1;
  148.         program_ctr=search_line((int)(*(VEC)(($2)->p)));
  149.       }}
  150.  
  151.     | Y_RETURN
  152.       { if(!transl_flag)
  153.         { if(gosub_ptr==0) { yyerror("return without gosub"); YYABORT; }
  154.           i=gosub_stack[--gosub_ptr];
  155.           program_ctr=search_line(i);
  156.       }}
  157.  
  158.     | Y_FOR Y_VAL '=' i_expr Y_TO i_expr f_step
  159.         { if(transl_flag)
  160.         {
  161.           tn=($2)->a;
  162.           if(tn!=(T_NODE *)NULL)
  163.             if(tn->c!=B_FOR)
  164.               { yyerror("variable unsuitable for loop"); YYABORT; }
  165.           sprintf(tmp_line,"?%s",($2)->s);
  166.           if((tn=t_symtable(tmp_line))==(T_NODE *)NULL)
  167.             t_error("Problem with FOR-loop.",-1);
  168.           if(tn->p==(void *)NULL)
  169.             {
  170.              if((tn->p=(void *)malloc(sizeof(FT_LOOP)))
  171.             ==(void *)NULL) t_error("No memory for loop.",1);
  172.              ft=(FT_LOOP *)(tn->p);
  173.              ft->n=-1; ft->start=0;
  174.              ft->step=1; ft->end=0;
  175.              tn->c=B_FOR;
  176.             }
  177.          ($2)->a=tn;
  178.         }
  179.           else /* !transl_flag */
  180.         { tn=($2)->a;
  181.           if((tn==(T_NODE *)NULL) || (tn->c!=B_FOR))
  182.             t_error("Unknown loop, probably array",-1);
  183.           ft=(FT_LOOP *)(tn->p);
  184.           if(program_ctr>0) ft->n=program[program_ctr-1].n+1;
  185.           else { yyerror("FOR outside program"); YYABORT; }
  186.           ft->start=$4; ft->step=$7; ft->end=$6;
  187.           *(VEC)(($2)->p)=ft->start; }
  188.         }
  189.  
  190.     | Y_NEXT Y_VAL
  191.       { if(!transl_flag)
  192.           { tn=($2)->a;
  193.         if((tn==(T_NODE *)NULL) || (tn->p==(void *)NULL)
  194.                     || (tn->c!=B_FOR))
  195.           { yyerror("NEXT without FOR"); YYABORT; }
  196.         ft=(FT_LOOP *)(tn->p);
  197.         if(*(VEC)(($2)->p)+ft->step <= ft->end)
  198.           { *(VEC)(($2)->p)+=ft->step;
  199.             program_ctr=search_line(ft->n); }
  200.         if(ybdebug)
  201.           fprintf(errlogz,"* loop   %G **\n",*(VEC)($2->p));
  202.           }}
  203.  
  204.  
  205.  
  206.     | Y_TRACE i_expr
  207.       { if(!transl_flag) ybdebug=($2);
  208.         switch(ybdebug)
  209.           {
  210.            case 1: errlogz=stderr; break;
  211.            case 2: errlogz=errlog; break;
  212.                case 3: errlogz=stderr; break;
  213.           }
  214.       }
  215.  
  216.     | Y_NEW { if(!transl_flag) { new(); program_ctr=-1; }}
  217.  
  218.     | Y_LET asn_expr
  219.     | asn_expr
  220.  
  221.     | Y_DIM Y_VAL dims
  222.       { if(!transl_flag)
  223.           {    for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
  224.         if(n<=0) { yyerror("scalar field dimension <=0"); YYABORT; }
  225.         if(ybdebug)
  226.           fprintf(errlogz,"* s size %ld **\n",n);
  227.         mkfield($2,&dm,n);
  228.       }}
  229.  
  230.     | Y_DIM Y_VEC dims
  231.       { if(!transl_flag)
  232.           {    for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
  233.         n*=3;
  234.         if(n<=0) { yyerror("vector field dimension <=0"); YYABORT; }
  235.         if(ybdebug)
  236.           fprintf(errlogz,"* v size %ld **\n",n);
  237.         mkfield($2,&dm,n);
  238.       }}
  239.  
  240.     | Y_DIM Y_BIT Y_VAL dims  /* last dim is bit number */
  241.       { if(!transl_flag)
  242.           {    for(i=0,n=1L;i<dm.n;i++) n*=dm.d[i];
  243.         if(n<=0) { yyerror("bit field dimension <=0"); YYABORT; }
  244.         n=(n-1)/(8*sizeof(double))+1;
  245.         if(ybdebug)
  246.           fprintf(errlogz,"* b size %ld*%d **\n",n,sizeof(double));
  247.         mkfield($3,&dm,n);
  248.       }}
  249.  
  250.     | Y_PRINT pr_exprs  { if(!transl_flag) printf("\n"); }
  251.  
  252.     | Y_FPRINT fp_exprs { if(!transl_flag) fprintf(pvp,"\n"); }
  253.  
  254.     | Y_LIST lst_expr
  255.            { if(!transl_flag) {
  256.             for(i=id1,n=0; (i<=id2) && (program[i].n>=0); i++,n++)
  257.               { printf("%-6d# %s\n",program[i].n,
  258.                   retransl_line(program[i].s));
  259.                 if(n && !(n%20)) gets(tmp_line);
  260.               }
  261.             printf("\n");
  262.            }}
  263.  
  264.     | Y_LOAD Y_STR
  265.       { if(!transl_flag)
  266.           { if(flev>=9) t_error("Maximum file depth reached.",4);
  267.         if((fp[++flev]=fopen((($2)->s)+1,"r"))==NULL)
  268.           { sprintf(err_msg,"can't open command file: %s",
  269.                 (($2)->s)+1);
  270.             yyerror(err_msg); flev-=1; YYABORT; }
  271.         load_flag=1; }}
  272.  
  273.     | Y_SAVE lst_expr Y_STR
  274.       { if(!transl_flag)
  275.           if(save_program(id1,id2,(($3)->s)+1)==NULL)
  276.         { sprintf(err_msg,"can't open save file: %s",(($3)->s)+1);
  277.           yyerror(err_msg); YYABORT; }
  278.           }
  279.  
  280.     | Y_SAVE Y_TRACE Y_STR
  281.       { if(!transl_flag)
  282.           { transl_flag=2;
  283.         if(save_program(0,MAX_LINES,(($3)->s)+1)==NULL)
  284.           { sprintf(err_msg,"can't open save file: %s",(($3)->s)+1);
  285.             yyerror(err_msg); YYABORT; }
  286.         transl_flag=0;
  287.           }
  288.           }
  289.  
  290.        | Y_FOPEN { if(!transl_flag)
  291.              { if(pvp!=stdout) fclose(pvp);
  292.                pvp=stdout;
  293.          }}
  294.        | Y_FOPEN Y_STR
  295.      { if(!transl_flag)
  296.          { if(pvp!=stdout) fclose(pvp);
  297.            if((pvp=fopen((($2)->s)+1,"a"))==NULL)
  298.           { sprintf(err_msg,"can't open output file: %s",
  299.                 (($2)->s)+1);
  300.             yyerror(err_msg); YYABORT; }
  301.      }}
  302.  
  303.     | Y_DELETE lst_expr
  304.       { if(!transl_flag)
  305.           for(i=id1; (i<=id2) && (program[id1].n>=0); i++)
  306.          insert_line(program[id1].n, (char *)NULL); }
  307.     | Y_DELETE Y_STR
  308.      { if(!transl_flag)
  309.          { if(pvp!=stdout) fclose(pvp);
  310.            if((pvp=fopen((($2)->s)+1,"w"))==NULL)
  311.           { sprintf(err_msg,"can't open output file: %s",
  312.                 (($2)->s)+1);
  313.             yyerror(err_msg); YYABORT; }
  314.      }}
  315.     | Y_DELETE Y_OBJ
  316.       { if(!transl_flag)
  317.           { free_obj($2);
  318.         if(ybdebug) obj_deb($2,0,errlogz);
  319.           }}
  320.     | Y_DELETE Y_TEX Y_OBJ
  321.       { if(!transl_flag)
  322.           { del_obj(($3)->tex); ($3)->tex=(POV_OBJ *)NULL;
  323.         if(ybdebug) obj_deb($3,0,errlogz);
  324.           }}
  325.     | Y_DELETE Y_BOUND Y_OBJ
  326.       { if(!transl_flag)
  327.           { del_obj(($3)->bound); ($3)->bound=(POV_OBJ *)NULL;
  328.         if(ybdebug) obj_deb($3,0,errlogz);
  329.           }}
  330.  
  331.     | Y_BOUND Y_OBJ
  332.       { if(!transl_flag) {
  333.           bound_obj($2); if(ybdebug) obj_deb($2,0,errlogz); }}
  334.  
  335. f_step  : { $$=1; }
  336.     | Y_STEP i_expr { $$=$2; }
  337.  
  338. asn_expr: y_val '=' i_expr { if(!transl_flag) *(VEC)(($1)->p)=$3; }
  339.  
  340.     | Y_BIT Y_VAL dims '=' i_expr
  341.       { if(!transl_flag)
  342.           {
  343.            dp=get_field(-sizeof(double),$2,&dm);
  344.            if(dp==(VEC)NULL) YYABORT;
  345.            id2=id1%(sizeof(int)*8); id1=id1/(sizeof(int)*8);
  346.            i=*((int *)dp+id1);
  347.            k=1; k=k<<id2; i=($5!=0) ? i|k : i&~k;
  348.            *((int *)dp+id1)=i;
  349.           }}
  350.  
  351.     | y_vec '=' v_expr
  352.       { if(!transl_flag)
  353.           for(i=0; i<3; i++) *((VEC)(($1)->p)+i)=($3)[i]; }
  354.  
  355.     | Y_OBJ '=' Y_STR
  356.       { if(!transl_flag)
  357.           { pv=$1;
  358.         if((pv->c>0) && (pv->s!=(char *)NULL))
  359.           for(ys=pv->s;*ys; ys+=5) del_obj(obj_all[get4hex(ys+1)]);
  360.         pv->c=0;
  361.         if(pv->s!=(char *)NULL) free(pv->s);
  362.         pv->s=cp_str((($3)->s)+1);
  363.         if(ybdebug) obj_deb($1,0,errlogz);
  364.           }}
  365.  
  366.     | Y_OBJ '=' y_obj
  367.       { if(!transl_flag)
  368.           { obj_asn($1,$3);
  369.         if(ybdebug) obj_deb($1,0,errlogz);
  370.           }}
  371.  
  372.     | Y_OBJ '=' v_expr { if(!transl_flag) vecasn(($1)->b,$3); }
  373.  
  374.     | Y_TEX Y_OBJ '=' y_obj
  375.       { if (!transl_flag)
  376.           { pv=($2)->tex;
  377.         if(pv!=(POV_OBJ *)NULL) { del_obj(pv); pv=(POV_OBJ *)NULL; }
  378.         ($2)->tex=obj_asn(pv,$4);
  379.         if(ybdebug) obj_deb($2,0,errlogz);
  380.           }}
  381.  
  382.     | Y_BOUND Y_OBJ '=' y_obj
  383.       { if (!transl_flag)
  384.           { pv=($2)->bound;
  385.         if(pv!=(POV_OBJ *)NULL) { del_obj(pv); pv=(POV_OBJ *)NULL; }
  386.         ($2)->bound=obj_asn(pv,$4);
  387.         if(ybdebug) obj_deb($2,0,errlogz);
  388.           }}
  389.  
  390.  
  391. pr_exprs: pr_expr
  392.     | pr_expr ',' pr_exprs
  393.  
  394. pr_expr : Y_STR  { if(!transl_flag) printf("%s",(($1)->s)+1); }
  395.     | i_expr { if(!transl_flag) printf(" %G",$1); }
  396.     | v_expr { if(!transl_flag)
  397.              printf(" <%G,%G,%G>",($1)[0],($1)[1],($1)[2]); }
  398.     | Y_OBJ  { if(!transl_flag) print_obj(stdout,$1); }
  399.  
  400. fp_exprs: fp_expr
  401.     | fp_expr ',' fp_exprs
  402.  
  403. fp_expr : Y_STR { if(!transl_flag) fprintf(pvp,"%s ",(($1)->s)+1); }
  404.     | i_expr { if(!transl_flag) fprintf(pvp," %G",$1); }
  405.     | v_expr { if(!transl_flag)
  406.              fprintf(pvp," <%G,%G,%G>",($1)[0],($1)[1],($1)[2]); }
  407.     | Y_OBJ  { if(!transl_flag) print_obj(pvp,$1); }
  408.  
  409. lst_expr: { id1=0;id2=MAX_LINES; }
  410.     | i_expr { id1=search_line((int)($1)); id2=MAX_LINES;}
  411.     | i_expr ',' i_expr { id1=search_line((int)($1));
  412.                   id2=search_line((int)($3)); }
  413.  
  414. dims    : { dm.n=0; } dimsz
  415.  
  416. dimsz   : dim
  417.     | dim dimsz
  418.  
  419. dim     : '[' i_exprx ']'
  420.        { if(!transl_flag)
  421.            { if(dm.n>=MAXDIM)
  422.            { sprintf(err_msg,"More than %d dimensions.",MAXDIM);
  423.              t_error(err_msg,4); }
  424.          dm.d[dm.n++]=(long)$2;
  425.          if(ybdebug)
  426.            fprintf(errlogz,"* dim    [%d] **\n",dm.d[dm.n-1]);
  427.        }}
  428.  
  429. obj_set : Y_OBJ ',' { obj_lst[0]=$1; n_obj=1; } obj_sez
  430.  
  431. obj_sez : s_obj
  432.     | s_obj ',' obj_sez
  433.  
  434. s_obj   : Y_OBJ  { if(!transl_flag)
  435.             { if(n_obj>=BSIZE) t_error("Too many objects",4);
  436.               obj_lst[n_obj++]=$1; }}
  437.  
  438. i_expr  : i_exprx { $$=$1;
  439.             if(ybdebug && !transl_flag)
  440.               fprintf(errlogz,"* scalar %G **\n",$$);
  441.           }
  442.  
  443. v_expr  : v_exprz { $$[0]=$1[0]; $$[1]=$1[1]; $$[2]=$1[2];
  444.             if(ybdebug && !transl_flag)
  445.               fprintf(errlogz,"* vector <%G,%G,%G> **\n",
  446.               $$[0],$$[1],$$[2]);
  447.           }
  448.  
  449. i_exprx : i_expry                  { $$=$1; }
  450.     | i_exprx '&' '&' i_expry  { $$=(($1)&&($4)); }
  451.     | i_exprx '|' '|' i_expry  { $$=(($1)||($4)); }
  452.  
  453.  
  454. i_expry    : i_exprz                  { $$=$1; }
  455.     | i_expry '<'     i_exprz  { $$=(($1)< ($3)); }
  456.     | i_expry '<' '=' i_exprz  { $$=(($1)<=($4)); }
  457.     | i_expry '='     i_exprz  { $$=(($1)==($3)); }
  458.     | v_exprz '='     v_exprz  { $$=((($1)[0]==($3)[0]) &&
  459.                      (($1)[1]==($3)[1]) &&
  460.                      (($1)[2]==($3)[2])); }
  461.     | i_expry '>'     i_exprz  { $$=(($1)> ($3)); }
  462.     | i_expry '>' '=' i_exprz  { $$=(($1)>=($4)); }
  463.     | i_expry '!' '=' i_exprz  { $$=(($1)!=($4)); }
  464.     | v_exprz '!' '=' v_exprz  { $$=((($1)[0]!=($4)[0]) ||
  465.                      (($1)[1]!=($4)[1]) ||
  466.                      (($1)[2]!=($4)[2])); }
  467.  
  468. i_exprz    : i_term                   { $$=$1; }
  469.     | i_exprz '+' i_term       { $$=(($1)+ ($3)); }
  470.     | i_exprz '-' i_term       { $$=(($1)- ($3)); }
  471.  
  472. i_term    : i_faktor                 { $$=$1; }
  473.     | i_term '*' i_faktor      { $$=(($1)* ($3)); }
  474.     | v_term '*' v_faktor      { $$=dot($1,$3); }
  475.     | i_term '/' i_faktor      { if(transl_flag) $$=0;
  476.                      else if($3!=0)  $$=(($1)/ ($3));
  477.                      else {
  478.                        yyerror("division by zero");
  479.                        YYABORT; }}
  480.     | i_term '%' i_faktor      { $$=fmod($1,$3); }
  481.  
  482. i_faktor: '-' i_faktor                { $$=-($2); }
  483.     | '!' i_faktor                { $$=!($2); }
  484.     | '@' i_faktor                { $$=($2)*M_PI/180; }
  485.     | '(' i_exprx ')'             { $$=$2; }
  486.     | Y_ABS '(' i_exprx ')'       { $$=fabs($3); }
  487.     | Y_ABS '(' v_exprz ')'       { $$=vecabs($3); }
  488.     | y_val                       { $$=*(VEC)(($1)->p); }
  489.     | Y_NUM                       { $$=*(VEC)(($1)->p); }
  490.     | Y_RND '(' i_exprx ')'       { $$=rnd($3); }
  491.     | Y_VX '(' v_exprz ')'        { $$=$3[0]; }
  492.     | Y_VY '(' v_exprz ')'        { $$=$3[1]; }
  493.     | Y_VZ '(' v_exprz ')'        { $$=$3[2]; }
  494.     | Y_FKT '(' i_exprx ')'
  495.       { if(!transl_flag) switch(fkt_id)
  496.           { case SIN: $$=sin($3); break;
  497.         case COS: $$=cos($3); break;
  498.         case TAN:  dd=cos($3);
  499.                if(dd==0) goto math_err;
  500.                $$=sin($3)/dd; break;
  501.         case ASIN: if(($3>1) || ($3<-1)) goto math_err;
  502.                $$=asin($3); break;
  503.         case ACOS: if(($3>1) || ($3<-1)) goto math_err;
  504.                $$=acos($3); break;
  505.         case ATAN: if(2*fabs($3)==M_PI/2) goto math_err;
  506.                $$=atan($3); break;
  507.         case EXP:  $$=exp($3); break;
  508.         case LOG:  if($3<=0) goto math_err;
  509.                $$=log($3); break;
  510.         case SQRT: if($3<0) goto math_err;
  511.                $$=sqrt($3); break;
  512.         case SQR:  $$=$3*$3; break;
  513.         math_err: yyerror("math error"); YYABORT;
  514.         default:  yyerror("wrong scalar->scalar function"); YYABORT;
  515.           }
  516.         else $$=0; }
  517.     | Y_FKT '(' i_exprx ',' i_exprx ')'
  518.       { if(!transl_flag) switch(fkt_id)
  519.           { case POW: $$=pow(($3),($5)); break;
  520.         default:  yyerror("wrong 2scalar->scalar function"); YYABORT;
  521.           }
  522.         else $$=0;
  523.       }
  524.     | Y_BIT Y_VAL dims
  525.       { if(!transl_flag)
  526.           {
  527.            dp=get_field(-sizeof(double),$2,&dm);
  528.            if(dp==(VEC)NULL) YYABORT;
  529.            i=*((int *)dp+id1/(sizeof(int)*8));
  530.            $$=(double)((i>>(id1%(sizeof(int)*8)))&1);
  531.           }
  532.         else $$=0;
  533.       }
  534.  
  535. y_val   : Y_VAL                       { $$=$1; }
  536.     | Y_VAL dims
  537.       { if(!transl_flag)
  538.           if(get_field(1,$1,&dm)==(VEC)NULL) YYABORT;
  539.           $$=$1; }
  540.  
  541. v_exprz    : v_term                   { vecasn($$,$1); }
  542.     | v_exprz '+' v_term        { vecadd($$,$1,$3); }
  543.     | v_exprz '-' v_term        { vecsub($$,$1,$3); }
  544.  
  545. v_term  : v_faktor                 { vecasn($$,$1); }
  546.     | i_term '*' v_faktor      { vecmul($$,$1,$3); }
  547.     | v_term '#' v_faktor      { vecprod($$,$1,$3); }
  548.  
  549. v_faktor: '(' v_exprz ')'           { vecasn($$,$2); }
  550.     | '<' i_exprz ',' i_exprz ',' i_exprz '>'
  551.        { ($$)[0]=$2; ($$)[1]=$4; ($$)[2]=$6; }
  552.     | y_vec
  553.       { for(i=0; i<3; i++) $$[i]=*((VEC)(($1)->p)+i); }
  554.     | '-' v_faktor             { vecneg($$,$2); }
  555.     | '@' v_faktor             { vecscale($$,M_PI/180,$2); }
  556.     | Y_RND '(' v_exprz ')' { for(i=0;i<3;i++) $$[i]=rnd(($3)[i]); }
  557.     | Y_V0 { $$[0]=0; $$[1]=0; $$[2]=0; }
  558.     | Y_VX { $$[0]=1; $$[1]=0; $$[2]=0; }
  559.     | Y_VY { $$[0]=0; $$[1]=1; $$[2]=0; }
  560.     | Y_VZ { $$[0]=0; $$[1]=0; $$[2]=1; }
  561.     | Y_V0 '(' Y_OBJ ')'    { vecasn($$,$3->b); }
  562.     | Y_VX '(' Y_OBJ ')'    { vecasn($$,$3->u); }
  563.     | Y_VY '(' Y_OBJ ')'    { vecasn($$,$3->v); }
  564.     | Y_VZ '(' Y_OBJ ')'    { vecasn($$,$3->w); }
  565.     | Y_FKT '(' v_exprz ',' v_exprz ')'
  566.       { if(!transl_flag) switch(fkt_id)
  567.           { case ROT: rotxyz($$,$3,$5); break;
  568.         case SCA: scale($$,$3,$5); break;
  569.         case PER: if(($3)[0]==0 && ($3)[1]==0 && ($3)[2]==0)
  570.                 vecasn($$,$5);
  571.               else
  572.                 { dd=dist2($3,$5); vecscale($$,dd,$3); }
  573.               break;
  574.         default:  yyerror("wrong vector->vector function"); YYABORT;
  575.           }
  576.         else $$[0]=$$[1]=$$[2]=0;
  577.       }
  578.     | Y_TRANSFORM '#' '(' v_exprz ',' v_exprz ',' v_exprz ',' v_exprz ')'
  579.       { if(!transl_flag) transformc($$,$4,$6,$8,$10); }
  580.  
  581.     | Y_TRANSFORM '(' v_exprz ',' v_exprz ',' v_exprz ',' v_exprz ')'
  582.       { if(!transl_flag)
  583.           { i=transformd($$,$3,$5,$7,$9);
  584.         if(!i) { yyerror("transformation impossible"); YYABORT; }
  585.           }}
  586.  
  587. y_vec   : Y_VEC { $$=$1; }
  588.     | Y_VEC dims
  589.       { if(!transl_flag)
  590.           if(get_field(3,$1,&dm)==(VEC)NULL) YYABORT;
  591.           $$=$1; }
  592.  
  593.  
  594. y_obj   : Y_OBJ { $$=$1; }
  595.  
  596.     | Y_TEX Y_OBJ
  597.       { if(!transl_flag)
  598.           if(($2)->tex!=(POV_OBJ *)NULL) $$=($2)->tex;
  599.           else { yyerror("Obj doesn't have a texture"); YYABORT; }
  600.       }
  601.  
  602.     | Y_BOUND Y_OBJ
  603.       { if(!transl_flag)
  604.           if(($2)->bound!=(POV_OBJ *)NULL) $$=($2)->bound;
  605.           else { yyerror("Obj doesn't have a bounding shape"); YYABORT; }
  606.       }
  607.  
  608.     | Y_PLANE '(' v_expr ',' v_expr ')'
  609.       { if(!transl_flag) $$=plane($3,$5); }
  610.  
  611.     | Y_PLANE '(' v_expr ',' v_expr ',' v_expr ')'
  612.       { if(!transl_flag)
  613.         { mknormal(v,$3,$5,$7);
  614.           $$=plane($3,v);
  615.         }}
  616.  
  617.  
  618.     | Y_FKT '(' Y_OBJ ',' v_expr ')'
  619.       { if(!transl_flag)
  620.           { pv=cp_tmp($3);
  621.         switch(fkt_id)
  622.           { case SCALE:       $$=yscale1(pv,$5);  break;
  623.             case ROTATE:      $$=yrot1(pv,$5);    break;
  624.             case TRANSLATE:   $$=ytransl1(pv,$5); break;
  625.             default:  yyerror("wrong obj/vec->obj function");
  626.                   YYABORT;
  627.           }
  628.           }
  629.         else $$=$3;
  630.       }
  631.  
  632.     | Y_FKT '#' '(' Y_OBJ ',' v_expr ')'
  633.       { if(!transl_flag)
  634.           { pv=cp_tmp($4);
  635.         switch(fkt_id)
  636.           { case SCALE:       $$=yscale2(pv,$6);  break;
  637.             case ROTATE:      $$=yrot2(pv,$6);    break;
  638.             case TRANSLATE:   $$=ytransl2(pv,$6); break;
  639.             default:  yyerror("wrong obj/vec->obj function(#)");
  640.                   YYABORT;
  641.           }
  642.           }
  643.         else $$=$4;
  644.       }
  645.  
  646.     | Y_FKT '(' obj_set ')'
  647.       { if(!transl_flag) switch(fkt_id)
  648.           { case CTDS:
  649.           if(n_obj<=2)
  650.             { if(($$=ctds(obj_lst[0],obj_lst[1]))==(POV_OBJ *)NULL)
  651.             { yyerror("ctds(2): object contains object");
  652.               YYABORT; }}
  653.           else
  654.             {
  655.               for(i=0;i<n_obj-1;i++)
  656.             { if((pv=ctds(obj_lst[i],obj_lst[i+1]))
  657.                   ==(POV_OBJ *)NULL)
  658.                 { yyerror("ctds(n): object contains object");
  659.                   YYABORT; }
  660.               obj_lst[i]=new_obj();
  661.               if(strlen(pv->s)>=LSIZE-1)
  662.                 t_error("Too much dots to connect.",4);
  663.               obj_lst[i]->s=cp_str(pv->s);
  664.               vecasn(obj_lst[i]->b,pv->b);
  665.               vecasn(obj_lst[i]->u,pv->u);
  666.               vecasn(obj_lst[i]->v,pv->v);
  667.               vecasn(obj_lst[i]->w,pv->w);
  668.             }
  669.               n_obj-=1; k=1;
  670.               goto la_csg0;
  671.             }
  672.           break;
  673.         case UNION: k=1; goto la_csg0;
  674.         case SECT:  k=2; goto la_csg0;
  675.         case DIFF:  k=3; goto la_csg0;
  676.         case ADDOBJ:
  677.                 pv=obj_lst[0];
  678.                 if(pv->c==0) { k=1; goto la_csg0; }
  679.                 add_objz(pv);
  680.                 /* pv will be copied !! */
  681.                 k=pv->c;
  682.                 cp_tmp(pv);
  683.                 pv_obj.cnt=-1;  pv_obj.c=1;
  684.                 pv_obj.s=cp_str(pv->s);
  685.  
  686.                 for(i=1;i<n_obj;i++)
  687.                   add_obj(&pv_obj,obj_lst[i]);
  688.                 goto la_csg1;
  689.  
  690.         la_csg0:    /* Adding to empty tmp object */
  691.                 vec0(pv_obj.b);  vecx(pv_obj.u);
  692.                 vecy(pv_obj.v);  vecz(pv_obj.w);
  693.                 pv_obj.cnt=-1;    pv_obj.c=1;
  694.                 pv_obj.s=(char *)NULL;
  695.                 pv_obj.tex=(POV_OBJ *)NULL;
  696.                 pv_obj.bound=(POV_OBJ *)NULL;
  697.  
  698.                 for(i=0;i<n_obj;i++)
  699.                   add_obj(&pv_obj,obj_lst[i]);
  700.  
  701.         la_csg1:    if(pv_obj.s!=(char *)NULL)
  702.                   { if(strlen(pv_obj.s)>=LSIZE-1)
  703.                   t_error("Too much objects in CSG.",4);
  704.                 strcpy(pv_line,pv_obj.s);
  705.                 free(pv_obj.s);
  706.                 pv_obj.s=pv_line;
  707.                   }
  708.                             pv_obj.c=k;
  709.                 $$=&pv_obj;
  710.                 break;
  711.  
  712.         default:   yyerror("wrong obj_set->obj function");
  713.                YYABORT;
  714.           }
  715.         else $$=&pv_obj;
  716.       }
  717.  
  718. %%
  719. int yyerror(char *s)
  720. {
  721.  fprintf(stderr,"%s : %s\n",yysccsid,s);
  722.  if(errlog!=stderr) fprintf(errlog,"YACC : %s\n",s);
  723.  return(0);
  724. }
  725.  
  726. void mkfield(T_NODE *tt, DIM_H *dm, long n)
  727. {
  728.  DIM_H *dmp;
  729.  T_NODE *tn;
  730.  static char msg[]="DIM array";
  731.  int i; long l;
  732.  
  733.  sprintf(tmp_line,"[]%s",tt->s);
  734.  if((tn=t_symtable(tmp_line))==(T_NODE *)NULL) t_error(msg,-1);
  735.  tt->a=tn;
  736.  
  737.  if(tn->p!=(void *)NULL) free((dmp=(DIM_H *)(tn->p))->f); /* kill field */
  738.  else { tn->p=(void *)(dmp=(DIM_H *)malloc(sizeof(DIM_H)));
  739.     if(dmp==(DIM_H *)NULL) t_error("Dim",1); }
  740.  
  741.  tn->c=B_FLD; dmp->n=dm->n;
  742.  for(i=0;i<dmp->n;i++) dmp->d[i]=dm->d[i];
  743.  
  744. #ifdef __TURBOC__
  745.  dmp->f=(VEC)farmalloc((unsigned long)(n*sizeof(double)));
  746. #else
  747.  dmp->f=(VEC)malloc((unsigned long)(n*sizeof(double)));
  748. #endif
  749.  
  750.  
  751.  if(dmp->f==(VEC)NULL)
  752.    { sprintf(err_msg,"Field %s[%ld] too large.",tt->s,n);
  753.      t_error(err_msg,1); }
  754.  for(l=0L;l<n;l++) *(dmp->f+l)=0;
  755.  dmp->l=n;
  756.  return;
  757. }
  758.  
  759. double *get_field(int nn, T_NODE *tnode, DIM_H *dm)
  760. {
  761.  T_NODE *tn;
  762.  DIM_H *dmp;
  763.  int i; long n,shift;
  764.  
  765.  tn=tnode->a;
  766.  if(tn==(T_NODE *)NULL || (tn->c!=B_FLD))
  767.    { yyerror("not a field"); return(double *)NULL; }
  768.  if(tn->p==(void *)NULL)
  769.    { yyerror("field with unknown dimension"); return(double *)NULL; }
  770.  dmp=(DIM_H *)(tn->p);
  771.  
  772.  if(dm->n!=dmp->n)
  773.    { yyerror("wrong number of indices"); return(double *)NULL;  }
  774.  for(i=0,n=0L,shift=1L;i<dm->n;i++)
  775.    { if((dm->d[i] > dmp->d[i]) || (dm->d[i]<=0))
  776.        { yyerror("index out of range"); return(double *)NULL;  }
  777.      n+=(dm->d[i]-1)*shift;
  778.      shift*=dmp->d[i];
  779.    }
  780.  id1=(int)(n%(-nn*8));
  781.  if(nn>0) n*=nn; else n=n/(-nn*8);
  782.  if(n>=dmp->l)
  783.    { yyerror("field length mismatch"); return((double *)NULL); }
  784.  tnode->p=(void *)((dmp->f)+n);
  785.  return((VEC)(tnode->p));
  786. }
  787.  
  788. double rnd(double r)
  789. { return( r*(double)(rand()&0X7FFF)/0X8000L ); }
  790.  
  791.  
  792. POV_OBJ *plane(VECTOR b,VECTOR a)
  793. {
  794.   vec0(pv_obj.b); vecx(pv_obj.u); vecy(pv_obj.v); vecz(pv_obj.w);
  795.   sprintf(pv_line,"plane { <%G,%G,%G>, %G }",
  796.           a[0],a[1],a[2],dot(a,b)/vecabs(a));
  797.   pv_obj.c=0; pv_obj.s=pv_line;
  798.   pv_obj.tex=pv_obj.bound=(POV_OBJ *)NULL;
  799.   pv_obj.cnt=1;
  800.   return(&pv_obj);
  801. }
  802.  
  803. /* Copies p to pv_obj        */
  804. POV_OBJ *cp_tmp(POV_OBJ *p)
  805. {
  806.   pv_obj.c=p->c; pv_obj.s=p->s;
  807.   pv_obj.tex=p->tex; pv_obj.bound=p->bound;
  808.   pv_obj.cnt=1;
  809.   vecasn(pv_obj.b,p->b);
  810.   vecasn(pv_obj.u,p->u);
  811.   vecasn(pv_obj.v,p->v);
  812.   vecasn(pv_obj.w,p->w);
  813.   return(&pv_obj);
  814. }
  815.  
  816. double obj_rad(POV_OBJ *p)
  817. { double x,y,z;
  818.   x=vecabs(p->u);
  819.   y=vecabs(p->v);
  820.   z=vecabs(p->w);
  821.   return((x+y+z)/3);
  822. }
  823.  
  824. /* create right angle vector                                    */
  825. void vec90(VECTOR rr,VECTOR v)
  826. {
  827.  int i,k;
  828.  VECTOR r;
  829.  
  830.  for(i=0,k=0; i<3; i++) { r[i]= (v[i]==0) ? 1 : 0; k+=(v[i]==0); }
  831.  if(!k)
  832.    { for(i=0; i<3; i++) r[i]=1/v[i]; r[2]=-2*r[2]; }
  833.  norm(rr,r);
  834.  return;
  835. }
  836.  
  837.  
  838. POV_OBJ *ctds(POV_OBJ *p1, POV_OBJ *p2)
  839. { double dd,r1,r2,a,sa,r,s1,s2;
  840.   VECTOR v,v1,v2,vu,vv,vw,vb;
  841.  
  842.   vecsub(v,p2->b,p1->b);
  843.   r1=obj_rad(p1); r2=obj_rad(p2);
  844.   r=r1-r2;
  845.   if(r==0)
  846.     {
  847.      vecasn(v1,p1->b);
  848.      vecasn(v2,p2->b);
  849.      s1=r1; s2=r2;
  850.     }
  851.   else
  852.     {
  853.      a=vecabs(v);
  854.      if((a==0) || (a<=fabs(r))) return((POV_OBJ *)NULL);
  855.      sa=r/a;            /* sinus alpha */
  856.      dd=sqrt(1/(sa*sa)-1);
  857.  
  858.      /* first cone rad:    r1*sa*dd */
  859.      /* second cone rad:   r2*sa*dd */
  860.      /* first cone point:  $3->b+(v)*sa*r1 */
  861.      /* second cone point: $5->b+(v)*sa*r2 */
  862.  
  863.      norm(v,v);
  864.      s1=r1*sa;               s2=r2*sa;
  865.      vecscale(v1,s1,v);      vecscale(v2,s2,v);
  866.      vecadd(v1,v1,p1->b);    vecadd(v2,v2,p2->b);
  867.      s1*=dd;                 s2*=dd;
  868.      s1=fabs(s1);            s2=fabs(s2);
  869.     }
  870.  
  871.   dd= (s1>s2) ? s1 : s2;
  872.   sprintf(pv_line,"cone {<-1,0,0>,%G,<1,0,0>,%G }",s1/dd,s2/dd);
  873.   vecasn(vb,v1);
  874.   vecsub(vu,v2,v1);
  875.   vecscale(vu,0.5,vu);
  876.   vecadd(vb,vb,vu);
  877.   vec90(vv,vu);
  878.   vecprod(vw,vv,vu);
  879.   norm(vw,vw);
  880.   vecscale(vv,dd,vv);
  881.   vecscale(vw,dd,vw);
  882.  
  883.  
  884. /*  vec0(vb); vecx(vu); vecy(vv); vecz(vw); *//* for debugging */
  885.  
  886.   vecasn(pv_obj.b,vb); vecasn(pv_obj.u,vu);
  887.   vecasn(pv_obj.v,vv); vecasn(pv_obj.w,vw);
  888.   pv_obj.c=(char)0; pv_obj.s=pv_line;
  889.   pv_obj.tex=(p1->tex==(POV_OBJ *)NULL) ? p2->tex : p1->tex;
  890.   pv_obj.bound=(POV_OBJ *)NULL;
  891.   pv_obj.cnt=1;
  892.   return(&pv_obj);
  893. }
  894.